package gen

import (
	"fmt"
	"game/game-design-v.xnanz/meta"
	"reflect"
	"strings"
)

type Expression struct {
	parent  *Expression
	child   *Expression
	content string
	value   any
}

func (e *Expression) Call() any {
	if strings.HasPrefix(e.content, "typeof") {
		e.value = typeof(fmt.Sprintf("%s", e.child.value))

	} else if strings.HasPrefix(e.content, "typeto") {
		e.value = typeto(fmt.Sprintf("%s", e.child.value))

	} else if strings.HasPrefix(e.content, "upper_first") {
		value := fmt.Sprintf("%v", e.child.value)
		e.value = strings.ToUpper(value[0:1]) + value[1:]

	} else if strings.HasPrefix(e.content, "not_empty") {
		e.value = not_empty(e.child.value.(reflect.Value))

	} else if strings.HasPrefix(e.content, "def_value") {
		e.value = def_value(fmt.Sprintf("%s", e.child.value))

	} else if strings.HasPrefix(e.content, "raw_type") {
		e.value = raw_typeto(fmt.Sprintf("%s", e.child.value))

	} else if strings.HasPrefix(e.content, "raw_def_value") {
		e.value = raw_def_value(fmt.Sprintf("%s", e.child.value))

	} else if strings.HasPrefix(e.content, "other") {
		return nil
	} else {
		parts := strings.Split(e.content, ".")
		var object interface{}
		for _, part := range parts {
			if object == nil {
				object = Params[part]
			} else {
				var rValue reflect.Value
				if reflect.TypeOf(object) == reflect.TypeOf(rValue) {
					rValue = object.(reflect.Value)
				} else {
					rValue = reflect.ValueOf(object)
				}
				rValue = rValue.Elem().FieldByName(part)
				object = rValue
			}
		}
		e.value = object
	}
	return e.value
}

func ParseFromExpression(str string) string {
	result := str
	for strings.Contains(result, "{{") && strings.Contains(result, "}}") {
		startIndex := strings.Index(result, "{{")
		endIndex := strings.Index(result, "}}")
		expression := result[startIndex+2 : endIndex]
		expValue := parse0(expression)
		result = strings.Replace(result, "{{"+expression+"}}", fmt.Sprintf("%s", expValue), 1)
	}
	return result
}

func GetFromExpression(str string) interface{} {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("error expression :", str, "of file", CurrFile)
		}
	}()
	result := str
	startIndex := strings.Index(result, "{{")
	endIndex := strings.Index(result, "}}")
	expression := result[startIndex+2 : endIndex]
	expValue := parse0(expression)
	return expValue
}

func parse0(expression string) any {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("error expression :", expression, "of file", CurrFile, err)
		}
	}()
	var exp Expression
	currExp := &exp
	for _, c := range expression {
		if c == '(' {
			var child Expression
			child.parent = currExp
			currExp.child = &child
			currExp = &child
		} else if c == ')' {
			currExp.Call()
			currExp = currExp.parent
		} else {
			currExp.content = fmt.Sprintf("%s%c", currExp.content, c)
		}
	}
	exp.Call()
	return exp.value
}

func typeof(field string) string {
	designMeta := Params["classMeta"].(*meta.DesignClassMeta)
	columnMeta, ok := designMeta.ColumnsMap[field]
	if !ok {
		fmt.Println("未找到名为", field, "的字段定义")
	}
	formatter := FormatMap[columnMeta.Form()]
	return formatter.FieldType
}

func typeto(form string) string {
	rawForm := strings.TrimSpace(form)
	inArray := false
	if strings.HasPrefix(rawForm, "[") && strings.HasSuffix(rawForm, "]") {
		rawForm = strings.Replace(rawForm, "[", "", 1)
		rawForm = strings.Replace(rawForm, "]", "", 1)
		inArray = true
	}
	formatter := FormatMap[rawForm]
	if formatter == nil {
		fmt.Println("类型无法解释：-" + form + "-")
		return form
	}
	fieldType := formatter.FieldType
	if inArray {
		wrapperType, ok := WrapperMap[fieldType]
		if ok {
			fieldType = wrapperType
		}
		fieldType = strings.Replace(List.Pattern, "{{}}", fieldType, 1)
	}
	return fieldType
}

func not_empty(rValue reflect.Value) bool {
	return rValue.Len() > 0
}

func def_value(form string) string {
	rawForm := form
	if strings.HasPrefix(rawForm, "[") && strings.HasSuffix(rawForm, "]") {
		return List.DefaultValue
	} else {
		formatter := FormatMap[rawForm]
		if formatter == nil {
			fmt.Println("类型无法解释：", form)
			return form
		}
		return formatter.DefaultValue
	}
}

func raw_typeto(form string) string {
	rawForm := form
	rawForm = strings.Replace(rawForm, "[", "", 1)
	rawForm = strings.Replace(rawForm, "]", "", 1)
	formatter := FormatMap[rawForm]
	if formatter == nil {
		fmt.Println("类型无法解释：", form)
		return form
	}
	return formatter.FieldType
}

func raw_def_value(form string) string {
	rawForm := form
	rawForm = strings.Replace(rawForm, "[", "", 1)
	rawForm = strings.Replace(rawForm, "]", "", 1)
	formatter := FormatMap[rawForm]
	if formatter == nil {
		fmt.Println("类型无法解释：", form)
		return form
	}
	return formatter.DefaultValue
}
